package com.example.examsystem.service;

import com.example.examsystem.dto.QuestionDto;
import com.example.examsystem.common.PageResponse;
import com.example.examsystem.enums.QuestionType;
import com.example.examsystem.exception.BusinessException;
import com.example.examsystem.model.Question;
import com.example.examsystem.repository.QuestionRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 试题服务
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class QuestionService {
    
    private final QuestionRepository questionRepository;
    
    /**
     * 获取试题列表（支持更多筛选条件）
     */
    public PageResponse<QuestionDto> getQuestions(int page, int size, String query, 
                                                 QuestionType type, Integer difficulty,
                                                 Long subjectId, Long categoryId) {
        Pageable pageable = PageRequest.of(page, size, Sort.by("createdAt").descending());
        
        String typeStr = type != null ? type.name() : null;
        Page<Question> questionPage = questionRepository.findByQueryWithFilters(
            query, typeStr, difficulty, subjectId, categoryId, pageable);
        
        List<QuestionDto> content = questionPage.getContent().stream()
            .map(this::convertToDto)
            .collect(Collectors.toList());
        
        return new PageResponse<>(
            content,
            questionPage.getNumber(),
            questionPage.getSize(),
            questionPage.getTotalElements(),
            questionPage.getTotalPages()
        );
    }
    
    /**
     * 根据ID获取试题
     */
    public QuestionDto getQuestionById(Long id) {
        log.debug("根据ID获取试题 - ID: {}", id);
        Question question = questionRepository.findById(id)
            .orElseThrow(() -> new BusinessException("试题不存在"));
        return convertToDto(question);
    }
    
    /**
     * 创建试题
     */
    @Transactional
    public QuestionDto createQuestion(QuestionDto questionDto) {
        log.debug("创建试题 - 标题: {}", questionDto.getTitle());
        
        Question question = new Question();
        question.setTitle(questionDto.getTitle());
        question.setContent(questionDto.getContent());
        question.setType(QuestionType.valueOf(questionDto.getType()));
        question.setDifficulty(questionDto.getDifficulty());
        question.setScore(questionDto.getScore());
        question.setSubjectId(questionDto.getSubjectId());
        question.setCategoryId(questionDto.getCategoryId());
        question.setAnswer(questionDto.getAnswer());
        question.setExplanation(questionDto.getExplanation());
        question.setCreatedAt(LocalDateTime.now());
        question.setUpdatedAt(LocalDateTime.now());
        
        // 处理选项 - 转换类型
        if (questionDto.getOptions() != null && !questionDto.getOptions().isEmpty()) {
            List<Question.QuestionOption> questionOptions = questionDto.getOptions().stream()
                .map(dto -> {
                    Question.QuestionOption option = new Question.QuestionOption();
                    option.setContent(dto.getContent());
                    option.setCorrect(dto.isCorrect());
                    return option;
                })
                .collect(Collectors.toList());
            question.setOptions(questionOptions);
        }
        
        Question saved = questionRepository.save(question);
        log.info("试题创建成功 - ID: {}, 标题: {}", saved.getId(), saved.getTitle());
        
        return convertToDto(saved);
    }
    
    /**
     * 更新试题
     */
    @Transactional
    public QuestionDto updateQuestion(Long id, QuestionDto questionDto) {
        log.debug("更新试题 - ID: {}, 标题: {}", id, questionDto.getTitle());
        
        Question question = questionRepository.findById(id)
            .orElseThrow(() -> new BusinessException("试题不存在"));
        
        question.setTitle(questionDto.getTitle());
        question.setContent(questionDto.getContent());
        question.setType(QuestionType.valueOf(questionDto.getType()));
        question.setDifficulty(questionDto.getDifficulty());
        question.setScore(questionDto.getScore());
        question.setSubjectId(questionDto.getSubjectId());
        question.setCategoryId(questionDto.getCategoryId());
        question.setAnswer(questionDto.getAnswer());
        question.setExplanation(questionDto.getExplanation());
        question.setUpdatedAt(LocalDateTime.now());
        
        // 处理选项 - 转换类型
        if (questionDto.getOptions() != null) {
            List<Question.QuestionOption> questionOptions = questionDto.getOptions().stream()
                .map(dto -> {
                    Question.QuestionOption option = new Question.QuestionOption();
                    option.setContent(dto.getContent());
                    option.setCorrect(dto.isCorrect());
                    return option;
                })
                .collect(Collectors.toList());
            question.setOptions(questionOptions);
        }
        
        Question updated = questionRepository.save(question);
        log.info("试题更新成功 - ID: {}, 标题: {}", id, updated.getTitle());
        
        return convertToDto(updated);
    }
    
    /**
     * 删除试题
     */
    @Transactional
    public void deleteQuestion(Long id) {
        log.debug("删除试题 - ID: {}", id);
        
        Question question = questionRepository.findById(id)
            .orElseThrow(() -> new BusinessException("试题不存在"));
        
        // TODO: 检查是否被考试使用
        
        questionRepository.delete(question);
        log.info("试题删除成功 - ID: {}, 标题: {}", id, question.getTitle());
    }
    
    /**
     * 导入试题
     */
    @Transactional
    public int importQuestions(MultipartFile file) throws IOException {
        // TODO: 实现Excel导入逻辑
        // 这里需要使用Apache POI来解析Excel文件
        return 0;
    }
    
    /**
     * 转换为DTO
     */
    private QuestionDto convertToDto(Question question) {
        QuestionDto dto = new QuestionDto();
        dto.setId(question.getId());
        dto.setTitle(question.getTitle());
        dto.setContent(question.getContent());
        dto.setType(question.getType().name());
        dto.setTypeName(question.getType().getTypeName(question.getType().name()));
        dto.setDifficulty(question.getDifficulty());
        dto.setScore(question.getScore());
        dto.setSubjectId(question.getSubjectId());
        dto.setCategoryId(question.getCategoryId());
        dto.setAnswer(question.getAnswer());
        dto.setExplanation(question.getExplanation());
        dto.setCreatedBy(question.getCreatedBy());
        dto.setCreatedAt(question.getCreatedAt());
        dto.setUpdatedAt(question.getUpdatedAt());
        
        // 转换选项
        List<Question.QuestionOption> questionOptions = question.getOptionsList();
        if (questionOptions != null && !questionOptions.isEmpty()) {
            List<QuestionDto.QuestionOptionDto> optionDtos = questionOptions.stream()
                .map(option -> {
                    QuestionDto.QuestionOptionDto optionDto = new QuestionDto.QuestionOptionDto();
                    optionDto.setContent(option.getContent());
                    optionDto.setCorrect(option.isCorrect());
                    return optionDto;
                })
                .collect(Collectors.toList());
            dto.setOptions(optionDtos);
        }
        
        // 设置关联信息
        if (question.getSubject() != null) {
            dto.setSubjectName(question.getSubject().getName());
        }
        if (question.getCategory() != null) {
            dto.setCategoryName(question.getCategory().getName());
        }
        
        return dto;
    }
}